/*! \file ModPerUsr.c
	\brief Modulo Percistencia Usuario.

As responsabilidades do Modulo Percistencia Usuario e de gericiar o
arquivo responsavel por salvar os ususarios em um arquivo e gerenciar esses detro do arquivo.\n

Arquivo : o Arquivo sera um arquivo de resgistros de tamanho fixo que tera as sequintes caracteristicas:\n
|campo 1= 11 digitos|campo 2= 15 digitos|campo 3= 4 digitos|campo 4= 1 digito|campo 5= 1 digito|campo 6=  1 digito\n

campo 1= chave primeria cpf\n
campo 2= chave secundaria nome \n
campo 3= senha\n
campo 4= numero de tentativas erradas\n
campo 5= numero de albums do usuario\n
campo 6= Usuario Bloqueado
 */

#define PerUsr_Serv
#include "InPerUsr.h"
/*! \fn int FechaArqui_PU (FILE* Arqui);
   \brief Responsavel por frechar o arquivo
   \param Aruqi : Arquivo a ser fecahdo
   \return Um int que funciona com "bool":\n
      0 -  Sucesso\n
*/
int FechaArqui_PU (FILE*);

/*! \fn int ValidaOperacao_PU (int TipoErro);
   \brief Responsavel por validar uma op do vetor de bits
   \param TipoErro : o tipo de erro que veio do vet bits
   \return Um int que funciona com "bool":\n
      0 -  Sucesso\n
     NG -  Erro de Banco de Dados\n
*/
int ValidaOperacao_PU (int);

/*! \fn int EncontraUsuario_PU (FILE* Arqui, const char* CpfPass);
   \brief Responsavel achar um usuario
   \param Arqui : o arquivo onde vai procurar
   \param CpfPass : o cpf a se encontrar.
   \return Um int que funciona com "bool":\n
      0 -  Sucesso\n
     NG -  nao econtrado
*/
int EncontraUsuario_PU (FILE*, const char*);

int FechaArqui_PU (FILE* Arqui) //comentar
{
	fclose (Arqui);
	return 0;
}

int ValidaOperacao_PU (int TipoErro) //comentar / interface
{
	char Exten[] = EXTENCAO_PU, NomeArqui[] = NARQUIVO_PU;
	int Retor = TipoErro;

	if (TipoErro == -1)
	{
		Retor = ReatualizacaoVetBits_VB (NomeArqui, Exten, TAMANHOREG_PU, VARIAVELCONTROLE_PU);
	}

	Retor *= 100;
	return Retor;
}

int EncontraUsuario_PU (FILE *ArquiTexto, const char* CpfPass) //comentar / interface / Ver se retorna -1
{
	char CpfPego[12];
	int i, PosicRegis = 0;

	CpfPego[0] = fgetc (ArquiTexto);
	while (!feof (ArquiTexto))
	{
		for (i = 1; i < 11; i++)
		{
			CpfPego[i] = fgetc (ArquiTexto);

		}
		CpfPego[i] = '\0';

		if (strcmp (CpfPego, CpfPass) == 0)
		{
			return PosicRegis;
		}
		else
		{
			fseek (ArquiTexto, (TAMANHOREG_PU - 11) + 2, SEEK_CUR);
			PosicRegis++;
		}
		CpfPego[0] = fgetc (ArquiTexto);
	}

	return -1;
}

int VerificaSenha_PU (const char* CpfPass, const char* SenhaPass) //testar, comentar, fclose
{
	FILE *ArquiTexto;
	char SenhaPega[5], NumerTenta, UsuarBlock;
	int i, PosicRegis;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

	if (PosicRegis == -1)
	{
		FechaArqui_PU (ArquiTexto);
		return -2;
	}

	fseek (ArquiTexto, ((PosicRegis * (TAMANHOREG_PU + 2))+(28)), SEEK_SET);

	for (i = 0; i < 4; i++)
	{
		SenhaPega[i] = fgetc (ArquiTexto);
	}
    SenhaPega[4]='\0';

	fseek (ArquiTexto, 5, SEEK_CUR);
	fscanf (ArquiTexto, "%c", &UsuarBlock);
	fseek (ArquiTexto, -6, SEEK_CUR);

	if (UsuarBlock == '1')
	{
		FechaArqui_PU (ArquiTexto);
		return -3;
	}

	fseek (ArquiTexto, 1, SEEK_CUR);

	if (strcmp (SenhaPega, SenhaPass) == 0)
	{
		fprintf (ArquiTexto, "0");
		FechaArqui_PU (ArquiTexto);
		return 0;
	}
	else
	{
		NumerTenta = fgetc (ArquiTexto);
		NumerTenta++;
		fseek (ArquiTexto, -1, SEEK_CUR);
		fprintf (ArquiTexto, "%c", NumerTenta);
		FechaArqui_PU (ArquiTexto);
		return (NumerTenta - 48);
	}
}

int BloqueiaUsuario_PU (const char* CpfPass) //comentar, testar, fclose
{
	int PosicRegis;
	FILE *ArquiTexto;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

	fseek (ArquiTexto, ((PosicRegis * (TAMANHOREG_PU + 2))+(37)), SEEK_SET);
	fprintf (ArquiTexto, "1");

	FechaArqui_PU (ArquiTexto);

	return 0;
}

int LiberaUsuario_PU (const char* CpfPass) //comentar, testar, fclose
{
	int PosicRegis = 0;
	FILE *ArquiTexto;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

    if (PosicRegis < 0)
    {
        return -2;
    }

	fseek (ArquiTexto, ((PosicRegis * (TAMANHOREG_PU + 2))+(33)), SEEK_SET);
	fprintf (ArquiTexto, "0");

	fseek (ArquiTexto, ((PosicRegis * (TAMANHOREG_PU + 2))+(37)), SEEK_SET);
	fprintf (ArquiTexto, "0");

	FechaArqui_PU (ArquiTexto);
	return 0;
}

int PegaUser_PU (const char* CpfPass, User_PU* DadosUsuar) //comentar, testar, fclose
{
	int PosicRegis, i;
	FILE *ArquiTexto;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

    if (PosicRegis<0)
    {
        return -2;
    }

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)), SEEK_SET);

	for (i = 0; i < 11; i++)
	{
		fscanf (ArquiTexto, "%c", &DadosUsuar->Cpf[i]);
	}
	DadosUsuar->Cpf[11] = '\0';

	fseek (ArquiTexto, 1, SEEK_CUR);

	for (i = 0; i < 15; i++)
	{
		fscanf (ArquiTexto, "%c", &DadosUsuar->Nome[i]);
	}
	DadosUsuar->Nome[15] = '\0';

	fseek (ArquiTexto, 1, SEEK_CUR);

	for (i = 0; i < 4; i++)
	{
		fscanf (ArquiTexto, "%c", &DadosUsuar->Senha[i]);
	}
	DadosUsuar->Senha[4] = '\0';

	fseek (ArquiTexto, 3, SEEK_CUR);

	fscanf (ArquiTexto, "%d", &DadosUsuar->NumerAlbum);

	return 0;

}

int AtualizaUser_PU (User_PU* DadosUsuar)//comentat, testar, fazer interface
{
	int PosicRegis, i;
	FILE *ArquiTexto;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, DadosUsuar->Cpf);
	if (PosicRegis < 0)
	{
		return -2;
	}

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)), SEEK_SET);

	fseek (ArquiTexto, 12, SEEK_CUR);

	for (i = 0; i < 15; i++)
	{
		fprintf (ArquiTexto, "%c", DadosUsuar->Nome[i]);
	}

	fseek (ArquiTexto, 1, SEEK_CUR);

	for (i = 0; i < 4; i++)
	{
		fprintf (ArquiTexto, "%c", DadosUsuar->Senha[i]);
	}

	FechaArqui_PU (ArquiTexto);
	return 0;
}

int DeletaUser_PU (const char* CpfPass)//comentar
{
	FILE *ArquiTexto;
	int PosicRegis, ValidOpera, ErroSuces;
	char NomeArqui[] = NARQUIVO_PU;
	char Varia = VARIAVELCONTROLE_PU;
	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

	if (PosicRegis == -1)
	{
		return -2;
	}

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)), SEEK_SET);

	fprintf (ArquiTexto, "%c", Varia);

	ValidOpera = LiberaRegistro_VB (PosicRegis+1, NomeArqui);

	FechaArqui_PU (ArquiTexto);

	ErroSuces = ValidaOperacao_PU (ValidOpera);

	return ErroSuces;
}

int AddUsuario_PU (User_PU* NovoUsuar)//comentat, testar, fazer interface
{
	char NomeArqui[] = NARQUIVO_PU;
	int NovaPosic, ErroSuces, i;
	FILE *ArquiTexto;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	NovaPosic = EncontraUsuario_PU (ArquiTexto, NovoUsuar->Cpf);
	if (NovaPosic >= 0)
	{
		return -2;
	}

	NovaPosic = PreencheRegistro_VB (NomeArqui);

	if (NovaPosic < 0)
	{
		ErroSuces = ValidaOperacao_PU (NovaPosic);

		NovaPosic = PreencheRegistro_VB (NomeArqui);

		if (ErroSuces < 0)
		{
			return ErroSuces;
		}

		if (NovaPosic < 0)
		{
			return NovaPosic * 100;
		}
	}

	fseek (ArquiTexto, ((NovaPosic - 1)*(TAMANHOREG_PU + 2)), SEEK_SET);

	for (i = 0; i < 11; i++)
	{
		fprintf (ArquiTexto, "%c", NovoUsuar->Cpf[i]);
	}

	fprintf (ArquiTexto, "|");


	for (i = 0; i < 15; i++)
	{
		fprintf (ArquiTexto, "%c", NovoUsuar->Nome[i]);
	}

	fprintf (ArquiTexto, "|");

	for (i = 0; i < 4; i++)
	{
		fprintf (ArquiTexto, "%c", NovoUsuar->Senha[i]);
	}

	fprintf (ArquiTexto, "|0|0|0\n");

	FechaArqui_PU (ArquiTexto);

	return 0;
}

int AddAlbum_PU (const char* CpfPass)//comentat / interface
{

	int PosicRegis;
	FILE *ArquiTexto;
	char NumerAlbum = 0;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);
	if (PosicRegis < 0)
	{
		return -2;
	}

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)) + 35, SEEK_SET);

	NumerAlbum = fgetc (ArquiTexto);
	NumerAlbum++;

	fseek (ArquiTexto, -1, SEEK_CUR);

	fprintf (ArquiTexto, "%c", NumerAlbum);

	FechaArqui_PU (ArquiTexto);

	return (NumerAlbum - 48);
}

int RemoveAlbum_PU (const char* CpfPass)//comentat / interface
{

	int PosicRegis;
	FILE *ArquiTexto;
	char NumerAlbum = 0;

	ArquiTexto = fopen (ARQUIVO_PU, "r+w");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)) + 35, SEEK_SET);

	NumerAlbum = fgetc (ArquiTexto);
	NumerAlbum--;

	fseek (ArquiTexto, -1, SEEK_CUR);

	fprintf (ArquiTexto, "%c", NumerAlbum);

	FechaArqui_PU (ArquiTexto);

	return (NumerAlbum - 48);
}

int VerificaNumeroAlbuns_PU (const char* CpfPass)//comentat / interface
{
	int PosicRegis;
	FILE *ArquiTexto;
	char NumerAlbum;

	ArquiTexto = fopen (ARQUIVO_PU, "r");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	PosicRegis = EncontraUsuario_PU (ArquiTexto, CpfPass);

	fseek (ArquiTexto, (PosicRegis * (TAMANHOREG_PU + 2)) + 35, SEEK_SET);

	NumerAlbum = fgetc (ArquiTexto);

	FechaArqui_PU (ArquiTexto);

	return (NumerAlbum - 48);
}

int ListaBloqueados_PU (User_PU *Usuar, int Pulo)
{
	//variaveis
	FILE *ArquiTexto;
	char Lixo, Bloqu;
	int PosicAtual = 1, i = 0;

	ArquiTexto = fopen (ARQUIVO_PU, "r");

	if (ArquiTexto == NULL)
	{
		return -1;
	}

	fseek (ArquiTexto, Pulo * (TAMANHOREG_PU + 2), SEEK_SET);

	fscanf (ArquiTexto, "%c", &Lixo);
	while (!feof (ArquiTexto))
	{
		fseek (ArquiTexto, 36, SEEK_CUR);
		fscanf (ArquiTexto, "%c", &Bloqu);
		if (Bloqu == '1')
		{
			fseek (ArquiTexto, -38, SEEK_CUR);

			for (i = 0; i < 11; i++)
			{
				Usuar->Cpf[i] = fgetc (ArquiTexto);
			}
			Usuar->Cpf[i] = '\0';

			fseek (ArquiTexto, 1, SEEK_CUR);
			for (i = 0; i < 15; i++)
			{
				Usuar->Nome[i] = fgetc (ArquiTexto);
			}
			Usuar->Nome[i] = '\0';

			return (PosicAtual+Pulo);
		}

		PosicAtual++;

		fseek (ArquiTexto, 2, SEEK_CUR);
		fscanf (ArquiTexto, "%c", &Lixo);
	}

	return -2;
}
